#!/usr/bin/env python3
"""
真实可执行的小红书每日发布脚本
使用传统 Playwright 实现，不依赖 MCP
"""

import asyncio
import logging
import json
import random
from datetime import datetime
from pathlib import Path
from playwright.async_api import async_playwright

class RealDailyPublisher:
    def __init__(self):
        self.config = self.load_config()
        self.logger = logging.getLogger(__name__)
        self.setup_logging()
        
    def setup_logging(self):
        """设置日志"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('real_daily_publisher.log'),
                logging.StreamHandler()
            ]
        )
    
    def load_config(self):
        """加载配置"""
        return {
            "headless": False,  # 开发时设为 False，生产时设为 True
            "timeout": 30000,
            "retry_count": 3,
            "images_path": "images/",
            "storage_state": "xiaohongshu_session.json"
        }
    
    def generate_daily_content(self):
        """生成每日内容"""
        date_str = datetime.now().strftime("%Y年%m月%d日")
        day_of_week = datetime.now().weekday()
        
        weekly_themes = {
            0: "新周开始，满怀希望！",
            1: "坚持努力，永不放弃！", 
            2: "中周加油，继续前行！",
            3: "即将过半，再接再厉！",
            4: "周末将至，完美收官！",
            5: "周末快乐，享受生活！",
            6: "美好周日，充电时光！"
        }
        
        content = f"""📅 {date_str} 每日分享

{weekly_themes[day_of_week]}

✨ 今天想和大家分享一些生活中的美好瞬间～

生活就像一本书，每一天都是新的一页。让我们用心去感受，用爱去生活，在平凡中发现不平凡的美好！

愿每个人都能在忙碌的生活中，找到属于自己的小确幸 🌟

#每日分享 #生活感悟 #正能量 #美好生活"""
        
        return {
            "title": f"📅 {date_str} 生活分享",
            "content": content
        }
    
    async def ensure_logged_in(self, page):
        """确保已登录"""
        try:
            # 检查登录状态的多种方式
            login_indicators = [
                '.reds-avatar-border',
                '[data-testid="user-avatar"]', 
                '.avatar',
                '.user-info'
            ]
            
            for selector in login_indicators:
                try:
                    await page.wait_for_selector(selector, timeout=3000)
                    self.logger.info(f"✅ 检测到登录状态: {selector}")
                    return True
                except:
                    continue
                    
            self.logger.warning("❌ 未检测到登录状态")
            return False
            
        except Exception as e:
            self.logger.error(f"登录检查失败: {e}")
            return False
    
    async def upload_image(self, page, image_path):
        """上传图片"""
        try:
            # 等待文件选择器
            file_input = await page.wait_for_selector('input[type="file"]', timeout=10000)
            
            # 上传文件
            await file_input.set_input_files(image_path)
            self.logger.info(f"✅ 图片上传成功: {image_path}")
            
            # 等待上传完成
            await page.wait_for_selector('img[src*="upload"]', timeout=30000)
            await asyncio.sleep(2)
            
            return True
        except Exception as e:
            self.logger.error(f"❌ 图片上传失败: {e}")
            return False
    
    async def fill_content(self, page, content_data):
        """填写内容"""
        try:
            # 填写标题
            title_input = await page.wait_for_selector(
                'input[placeholder*="标题"], textbox[placeholder*="标题"]', 
                timeout=10000
            )
            await title_input.fill(content_data["title"])
            self.logger.info("✅ 标题填写完成")
            
            # 填写正文
            content_selectors = [
                'textbox:has-text("输入正文")',
                'div[contenteditable="true"]',
                'textarea[placeholder*="正文"]'
            ]
            
            content_filled = False
            for selector in content_selectors:
                try:
                    content_input = await page.wait_for_selector(selector, timeout=5000)
                    await content_input.fill(content_data["content"])
                    content_filled = True
                    self.logger.info("✅ 正文填写完成")
                    break
                except:
                    continue
            
            if not content_filled:
                raise Exception("无法找到正文输入框")
            
            return True
        except Exception as e:
            self.logger.error(f"❌ 内容填写失败: {e}")
            return False
    
    async def publish_post(self, page):
        """发布帖子"""
        try:
            # 查找发布按钮
            publish_selectors = [
                'button:has-text("发布")',
                'button[type="submit"]',
                '.publish-button',
                '[data-testid="publish-btn"]'
            ]
            
            published = False
            for selector in publish_selectors:
                try:
                    publish_btn = await page.wait_for_selector(selector, timeout=5000)
                    await publish_btn.click()
                    published = True
                    self.logger.info("✅ 点击发布按钮成功")
                    break
                except:
                    continue
            
            if not published:
                raise Exception("无法找到发布按钮")
            
            # 等待发布结果
            try:
                # 等待成功页面或成功提示
                success_indicators = [
                    'text=发布成功',
                    'text=发布完成', 
                    '[class*="success"]'
                ]
                
                for indicator in success_indicators:
                    try:
                        await page.wait_for_selector(indicator, timeout=15000)
                        self.logger.info("🎉 发布成功！")
                        return True
                    except:
                        continue
                
                # 如果没有明确的成功提示，检查是否跳转到成功页面
                current_url = page.url
                if 'success' in current_url or 'complete' in current_url:
                    self.logger.info("🎉 发布成功（通过URL判断）")
                    return True
                
                self.logger.warning("⚠️ 发布状态不明确")
                return False
                
            except Exception as e:
                self.logger.error(f"❌ 发布确认失败: {e}")
                return False
                
        except Exception as e:
            self.logger.error(f"❌ 发布操作失败: {e}")
            return False
    
    async def execute_publish(self):
        """执行发布流程"""
        async with async_playwright() as p:
            # 启动浏览器
            browser = await p.chromium.launch(
                headless=self.config["headless"],
                args=['--no-sandbox', '--disable-setuid-sandbox']
            )
            
            try:
                # 创建上下文，加载会话状态
                context_options = {}
                storage_state_path = Path(self.config["storage_state"])
                
                if storage_state_path.exists():
                    context_options["storage_state"] = str(storage_state_path)
                    self.logger.info("✅ 加载已保存的会话状态")
                
                context = await browser.new_context(**context_options)
                page = await context.new_page()
                
                # 设置超时
                page.set_default_timeout(self.config["timeout"])
                
                # 1. 导航到小红书创作页面
                await page.goto('https://creator.xiaohongshu.com')
                await page.wait_for_load_state('networkidle')
                
                # 2. 检查登录状态
                if not await self.ensure_logged_in(page):
                    self.logger.error("❌ 未登录，需要手动登录后再试")
                    return False
                
                # 3. 进入发布页面
                await page.goto('https://creator.xiaohongshu.com/publish/publish')
                await page.wait_for_load_state('networkidle')
                
                # 4. 选择图文发布
                try:
                    image_publish_btn = await page.wait_for_selector(
                        'text=发布图文笔记', timeout=10000
                    )
                    await image_publish_btn.click()
                    await asyncio.sleep(2)
                except Exception as e:
                    self.logger.error(f"❌ 无法找到图文发布按钮: {e}")
                    return False
                
                # 5. 上传图片（如果有）
                images_dir = Path(self.config["images_path"])
                if images_dir.exists():
                    image_files = list(images_dir.glob("*.jpg")) + list(images_dir.glob("*.png"))
                    if image_files:
                        if not await self.upload_image(page, str(image_files[0])):
                            return False
                
                # 6. 填写内容
                content_data = self.generate_daily_content()
                if not await self.fill_content(page, content_data):
                    return False
                
                # 7. 发布
                if not await self.publish_post(page):
                    return False
                
                # 8. 保存会话状态
                await context.storage_state(path=self.config["storage_state"])
                self.logger.info("✅ 会话状态已保存")
                
                return True
                
            finally:
                await browser.close()
    
    async def run_with_retry(self):
        """带重试的执行"""
        for attempt in range(self.config["retry_count"]):
            try:
                self.logger.info(f"🚀 开始执行发布任务 (第 {attempt + 1} 次尝试)")
                
                success = await self.execute_publish()
                if success:
                    self.logger.info("🎉 发布任务完成！")
                    return True
                else:
                    self.logger.warning(f"⚠️ 第 {attempt + 1} 次尝试失败")
                    
            except Exception as e:
                self.logger.error(f"❌ 第 {attempt + 1} 次尝试异常: {e}")
            
            # 失败后等待再重试
            if attempt < self.config["retry_count"] - 1:
                wait_time = (attempt + 1) * 60  # 递增等待时间
                self.logger.info(f"⏰ 等待 {wait_time} 秒后重试...")
                await asyncio.sleep(wait_time)
        
        self.logger.error("❌ 所有重试都失败了")
        return False

async def main():
    """主函数"""
    publisher = RealDailyPublisher()
    success = await publisher.run_with_retry()
    
    if success:
        print("✅ 每日发布任务成功完成")
        exit(0)
    else:
        print("❌ 发布任务失败")
        exit(1)

if __name__ == "__main__":
    asyncio.run(main())
